#   Copyright 2013 Stacy Doss stacy.doss@gmail.com
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

package DIME::View;

use strict;
use warnings;

use Tk;
use DIME::View::Menu;
use DIME::View::Browser;
use DIME::View::Edit;
use DIME::View::Command;
use DIME::View::Search;
use DIME::View::Info;
use DIME::View::Path;
use DIME::View::HList;
use DIME::View::Icons;
use DIME::Dlg::File;
use DIME::Dlg::Search;
use DIME::Utility;

our $VERSION = '0.01';


sub new {
	my $class = shift;
	my $app   = shift;
		
	my $T = {
        application => $app,
        root        => undef,
	};
		
	bless $T, $class;

    $T->mainWindow();
 
	return $T;
}


sub clearSearch {
    my $self = shift;
    
    $self->{dlg}{search}->clear();
}



sub destroy {
    my $self = shift;
    $self->{MW}->destroy();
}


sub display {
    my $self = shift;
    MainLoop;
}



sub Error {
    my $self = shift;
    my $message = shift;
    Tk::Error($self->{MW}, $message);
}



sub getApplication {
    my $self = shift;
    return $self->{application};
}



sub getEdit {
    my $self = shift;
    return $self->{edit};
}



sub getGrouping {
    my $self = shift;
    my $ref  = shift;
    
    if (hashref($ref)) {
        return ('{', '}');
    }    

    if (arrayref($ref)) {
        return ('[', ']');
    }
}



sub getIcon {
    my $self  = shift;
    my $state = shift;
    my $type  = shift;

    return $self->{icons}{icons}{$state}{$type};    
}



sub getOpenFilename {
    my $self = shift;

    my $dlg = new DIME::Dlg::File($self);
    return $dlg->getOpenFilename();
}



sub getPath {
    my $self = shift;
    return $self->{path};    
}



sub getRefType {
    my $self = shift;
    my $ref  = shift;
    
    if (hashref($ref)) {
        return '%';
    }    

    if (arrayref($ref)) {
        return '@';
    }
    
}

sub getSaveFilename {
    my $self = shift;
    my $type = shift;

    my $dlg = new DIME::Dlg::File($self);
    return $dlg->getSaveFilename($type);
}



sub mainWindow {
    my $self = shift;
    
    if (not $self->{MW}) {
        # Main Window
	    my $mw = $self->{MW} = new MainWindow();
        $mw->bind("<Control-q>", [sub {$self->cmdExit}]);

	    $mw->iconname('DIME');
	    $mw->configure(-bg => 'grey');
	    $mw->geometry('750x520+1+1');
    }
    
    $self->{menu}    = new DIME::View::Menu($self);
    $self->{info}    = new DIME::View::Info($self);
    $self->{cli}     = new DIME::View::Command($self);
    $self->{search}  = new DIME::View::Search($self);
    $self->{edit}    = new DIME::View::Edit($self);
    $self->{browser} = new DIME::View::Browser($self);
    $self->{hlist}   = new DIME::View::HList($self);
    $self->{path}    = new DIME::View::Path($self);
    $self->{icons}   = new DIME::View::Icons($self);
    
    $self->{dlg}{search} = new DIME::Dlg::Search($self);
 
    return $self->{MW};
}		



sub populateRoot {
    my $self = shift;
    my $data = shift;
    $self->{root} = $data;
    $self->{browser}->populate($data);
    $self->{hlist}->initialize($data);
}



sub removeDataFromViews {
    my $self = shift;
    $self->{browser}->removeColumns();
    $self->{hlist}{list}->deleteAll();
}



sub showOption {
    my $self   = shift;
    my $option = shift;
    my $show   = shift;

    # L@@K Need to add "filter"
    if ($option =~ m/cli|hlist|search|browser|path/) {
        my $view = $self->{$option};
        $self->{menu}{opts}{check}{$option} = $show;
        if ($show) {
            $view->show();
        } else {
            $view->hide();
        }
        return;
    }

    # L@@K need to implement
    if ($option =~ m/filter|undef/) {
        return;
    }

    print STDERR "Huh? Option $option can't be shown/hidden\n"
}



sub updatePath {
    my $self = shift;
    my $path = shift;
 
    my $ref = $self->{root};
    
    $self->{path}->clear();

    for my $part (@{$path}) {
        my $type = $self->getRefType($ref);
        $ref = $self->walkRef($ref, $part);
        $self->{path}->add($type, $part);
        
    }
}



sub walkRef {
    my $self = shift;
    my $ref  = shift;
    my $next = shift;
    
    if (hashref($ref)) {
        return $ref->{$next};
    }    

    if (arrayref($ref)) {
        return $ref->[$next];
    }
    
    return undef;
}

1;
